<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 使用 * 表示这是一个 Generator 函数
        // 内部可以通过 yield 暂停代码
        // 通过调用 next 恢复执行
        function* test() {
            let a = 1 + 2;
            yield 2;
            yield 3;
        }
        let b = test();
        console.log(b.next()); // >  { value: 2, done: false }
        console.log(b.next()); // >  { value: 3, done: false }
        console.log(b.next()); // >  { value: undefined, done: true }

        // cb 也就是编译过的 test 函数
        function generator(cb) {
            return (function (){
                var object = {
                    next: 0,
                    stop: function () {
                        
                    }
                };
                return {
                    next: function () {
                        var ret = cb(object);
                        if (ret === undefined) return { value: undefined, done: true };
                        return {
                            value: ret,
                            done: false
                        };
                    }
                };
            })();
        }
        // 如果你使用 babel 编译后可以发现 test 函数变成了这样
        function test() {
            var a;
            return generator(function (_context) {
                while (1) {
                    switch ((_context.prev = _context.next)) {
                        // 可以发现通过 yield 将代码分割成几块
                        // 每次执行 next 函数就执行一块代码
                        // 并且表明下次需要执行哪块代码
                        case 0:
                            a = 1 + 2;
                            _context.next = 4;
                            return 2;
                        case 4:
                            _context.next = 6;
                            return 3;
                        // 执行完毕
                        case 6:
                        case "end":
                            return _context.stop();
                    }
                }
            });
        }



    </script>
</body>

</html>